package api

import (
	"family/api/dto"
	"family/dao"
	"family/model"
	"family/pkg/constant"
	"family/pkg/response"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/spf13/cast"
	"time"
)

var PeopleAPI = new(peopleAPI)

type peopleAPI struct{}

func (*peopleAPI) Create(c *gin.Context) {
	var addDTO dto.PeopleAddDTO
	if err := c.ShouldBindJSON(&addDTO); err != nil {
		response.ERROR(c, response.Validate, err.Error())
		return
	}
	Birthday, err := time.Parse(constant.DATE, addDTO.Birthday)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	DeadTime, err := time.Parse(constant.DATE, addDTO.DeadTime)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	err = dao.PeopleDao.Create(&model.People{
		Parent:   cast.ToUint64(addDTO.Parent),
		Name:     addDTO.Name,
		Sex:      addDTO.Sex,
		Birthday: Birthday,
		DeadTime: DeadTime,
	})
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	response.OK(c, nil)
}

func (*peopleAPI) Details(c *gin.Context) {
	param := c.Param("ID")
	info, err := dao.PeopleDao.Info(param)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	DTO := &dto.PeopleDTO{
		ID:       cast.ToString(info.ID),
		Parent:   cast.ToString(info.Parent),
		Name:     info.Name,
		Sex:      info.Sex,
		Birthday: info.Birthday.Format(constant.DATE),
		DeadTime: info.DeadTime.Format(constant.DATE),
	}

	response.OK(c, DTO)
}

func (*peopleAPI) Page(c *gin.Context) {
	id := cast.ToUint64(c.Query("ID"))
	models, i, err := dao.PeopleDao.Page(id)
	if err != nil {
		return
	}
	var DTOS []*dto.PeopleDTO

	for _, item := range models {
		DTO := &dto.PeopleDTO{
			ID:       cast.ToString(item.ID),
			Parent:   cast.ToString(item.Parent),
			Name:     item.Name,
			Sex:      item.Sex,
			Birthday: item.Birthday.Format(constant.DATE),
			DeadTime: item.DeadTime.Format(constant.DATE),
		}
		DTOS = append(DTOS, DTO)
	}
	response.Page(c, i, DTOS)
}

func (*peopleAPI) Update(c *gin.Context) {
	var updateDTO dto.PeopleUpdateDTO
	if err := c.ShouldBindJSON(&updateDTO); err != nil {
		response.ERROR(c, response.Validate, err.Error())
		return
	}
	Birthday, err := time.Parse(constant.DATE, updateDTO.Birthday)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
	}
	DeadTime, err := time.Parse(constant.DATE, updateDTO.DeadTime)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
	}
	err = dao.PeopleDao.Update(&model.People{
		ID:       cast.ToUint64(updateDTO.ID),
		Parent:   cast.ToUint64(updateDTO.Parent),
		Name:     updateDTO.Name,
		Sex:      updateDTO.Sex,
		Birthday: Birthday,
		DeadTime: DeadTime,
	})
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	response.OK(c, nil)
}

func (*peopleAPI) Delete(c *gin.Context) {
	var deleteDTO dto.PeopleDeleteDTO
	if err := c.ShouldBindJSON(&deleteDTO); err != nil {
		response.ERROR(c, response.Validate, err.Error())
		return
	}
	err := dao.PeopleDao.Delete(deleteDTO.Ids)
	if err != nil {
		response.ERROR(c, response.UNIVERSAL, err.Error())
		return
	}
	response.OK(c, nil)
}

func (*peopleAPI) Tree(c *gin.Context) {
	id := cast.ToUint64(c.Query("ID"))
	models, _, err := dao.PeopleDao.Page(id)
	if err != nil {
		return
	}
	var DTOS []*dto.PeopleTreeDTO

	for _, item := range models {
		DTO := &dto.PeopleTreeDTO{
			ID:       cast.ToString(item.ID),
			Name:     item.Name,
			Sex:      item.Sex,
			Birthday: item.Birthday.Format(constant.DATE),
			DeadTime: item.DeadTime.Format(constant.DATE),
		}
		if item.Parent == 0 {
			DTO.Parent = ""
		} else {
			DTO.Parent = cast.ToString(item.Parent)
		}
		DTOS = append(DTOS, DTO)
	}
	fmt.Println(DTOS)
	response.OK(c, DTOS)
}
